using System.Collections.Generic;

//
// * Copyright (c) 2002-2009 "Neo Technology,"
// *     Network Engine for Objects in Lund AB [http://neotechnology.com]
// *
// * This file is part of Neo4j.
// * 
// * Neo4j is free software: you can redistribute it and/or modify
// * it under the terms of the GNU Affero General Public License as
// * published by the Free Software Foundation, either version 3 of the
// * License, or (at your option) any later version.
// * 
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// * GNU Affero General Public License for more details.
// * 
// * You should have received a copy of the GNU Affero General Public License
// * along with this program. If not, see <http://www.gnu.org/licenses/>.
// 
namespace org.neo4j.kernel.impl.core
{


	using Direction = org.neo4j.graphdb.Direction;
	using Node = org.neo4j.graphdb.Node;
	using NotFoundException = org.neo4j.graphdb.NotFoundException;
	using Relationship = org.neo4j.graphdb.Relationship;
	using RelationshipType = org.neo4j.graphdb.RelationshipType;
	using EmbeddedGraphDatabase = org.neo4j.kernel.EmbeddedGraphDatabase;
	using AbstractNeo4jTestCase = org.neo4j.kernel.impl.AbstractNeo4jTestCase;
	using MyRelTypes = org.neo4j.kernel.impl.MyRelTypes;
	using NeoModule = org.neo4j.kernel.impl.core.NeoModule;

	public class TestRelationship : AbstractNeo4jTestCase
	{
		private string key1 = "key1";
		private string key2 = "key2";
		private string key3 = "key3";

		public TestRelationship(string testName) : base(testName)
		{
		}

		public virtual void testSimple()
		{
			Node node1 = getGraphDb().createNode();
			Node node2 = getGraphDb().createNode();
			Relationship rel1 = node1.createRelationshipTo(node2, MyRelTypes.TEST);
			Relationship rel2 = node1.createRelationshipTo(node2, MyRelTypes.TEST);
			rel1.delete();
			newTransaction();
			assertTrue(node1.getRelationships().GetEnumerator().MoveNext());
			assertTrue(node2.getRelationships().GetEnumerator().MoveNext());
			assertTrue(node1.getRelationships(MyRelTypes.TEST).GetEnumerator().MoveNext());
			assertTrue(node2.getRelationships(MyRelTypes.TEST).GetEnumerator().MoveNext());
			assertTrue(node1.getRelationships(MyRelTypes.TEST, Direction.OUTGOING).GetEnumerator().MoveNext());
			assertTrue(node2.getRelationships(MyRelTypes.TEST, Direction.INCOMING).GetEnumerator().MoveNext());
		}

		public virtual void testSimple2()
		{
			Node node1 = getGraphDb().createNode();
			Node node2 = getGraphDb().createNode();
			for (int i = 0; i < 3; i++)
			{
				node1.createRelationshipTo(node2, MyRelTypes.TEST);
				node1.createRelationshipTo(node2, MyRelTypes.TEST_TRAVERSAL);
				node1.createRelationshipTo(node2, MyRelTypes.TEST2);
			}
			allGetRelationshipMethods(node1, Direction.OUTGOING);
			allGetRelationshipMethods(node2, Direction.INCOMING);
			newTransaction();
			allGetRelationshipMethods(node1, Direction.OUTGOING);
			allGetRelationshipMethods(node2, Direction.INCOMING);
			node1.getRelationships(MyRelTypes.TEST, Direction.OUTGOING).GetEnumerator().Current.delete();
			node1.getRelationships(MyRelTypes.TEST_TRAVERSAL, Direction.OUTGOING).GetEnumerator().Current.delete();
			node1.getRelationships(MyRelTypes.TEST2, Direction.OUTGOING).GetEnumerator().Current.delete();
			node1.createRelationshipTo(node2, MyRelTypes.TEST);
			node1.createRelationshipTo(node2, MyRelTypes.TEST_TRAVERSAL);
			node1.createRelationshipTo(node2, MyRelTypes.TEST2);
			allGetRelationshipMethods(node1, Direction.OUTGOING);
			allGetRelationshipMethods(node2, Direction.INCOMING);
			newTransaction();
			allGetRelationshipMethods(node1, Direction.OUTGOING);
			allGetRelationshipMethods(node2, Direction.INCOMING);
			foreach (Relationship rel in node1.getRelationships())
			{
				rel.delete();
			}
			node1.delete();
			node2.delete();
		}

		public virtual void testSimple3()
		{
			Node node1 = getGraphDb().createNode();
			Node node2 = getGraphDb().createNode();
			for (int i = 0; i < 1; i++)
			{
				node1.createRelationshipTo(node2, MyRelTypes.TEST);
				node1.createRelationshipTo(node2, MyRelTypes.TEST_TRAVERSAL);
				node1.createRelationshipTo(node2, MyRelTypes.TEST2);
			}
			allGetRelationshipMethods2(node1, Direction.OUTGOING);
			allGetRelationshipMethods2(node2, Direction.INCOMING);
			newTransaction();
			allGetRelationshipMethods2(node1, Direction.OUTGOING);
			allGetRelationshipMethods2(node2, Direction.INCOMING);
			node1.getRelationships(MyRelTypes.TEST, Direction.OUTGOING).GetEnumerator().Current.delete();
			node1.getRelationships(MyRelTypes.TEST_TRAVERSAL, Direction.OUTGOING).GetEnumerator().Current.delete();
			node1.getRelationships(MyRelTypes.TEST2, Direction.OUTGOING).GetEnumerator().Current.delete();
			node1.createRelationshipTo(node2, MyRelTypes.TEST);
			node1.createRelationshipTo(node2, MyRelTypes.TEST_TRAVERSAL);
			node1.createRelationshipTo(node2, MyRelTypes.TEST2);
			allGetRelationshipMethods2(node1, Direction.OUTGOING);
			allGetRelationshipMethods2(node2, Direction.INCOMING);
			newTransaction();
			allGetRelationshipMethods2(node1, Direction.OUTGOING);
			allGetRelationshipMethods2(node2, Direction.INCOMING);
			foreach (Relationship rel in node1.getRelationships())
			{
				rel.delete();
			}
			node1.delete();
			node2.delete();
		}

		public virtual void testSimple4()
		{
			Node node1 = getGraphDb().createNode();
			Node node2 = getGraphDb().createNode();
			for (int i = 0; i < 2; i++)
			{
				node1.createRelationshipTo(node2, MyRelTypes.TEST);
				node1.createRelationshipTo(node2, MyRelTypes.TEST_TRAVERSAL);
				node1.createRelationshipTo(node2, MyRelTypes.TEST2);
			}
			allGetRelationshipMethods3(node1, Direction.OUTGOING);
			allGetRelationshipMethods3(node2, Direction.INCOMING);
			newTransaction();
			allGetRelationshipMethods3(node1, Direction.OUTGOING);
			allGetRelationshipMethods3(node2, Direction.INCOMING);
			node1.getRelationships(MyRelTypes.TEST, Direction.OUTGOING).GetEnumerator().Current.delete();
			int count = 0;
			foreach (Relationship rel in node1.getRelationships(MyRelTypes.TEST_TRAVERSAL, Direction.OUTGOING))
			{
				if (count == 1)
				{
					rel.delete();
				}
				count++;
			}
			node1.getRelationships(MyRelTypes.TEST2, Direction.OUTGOING).GetEnumerator().Current.delete();
			node1.createRelationshipTo(node2, MyRelTypes.TEST);
			node1.createRelationshipTo(node2, MyRelTypes.TEST_TRAVERSAL);
			node1.createRelationshipTo(node2, MyRelTypes.TEST2);
			allGetRelationshipMethods3(node1, Direction.OUTGOING);
			allGetRelationshipMethods3(node2, Direction.INCOMING);
			newTransaction();
			allGetRelationshipMethods3(node1, Direction.OUTGOING);
			allGetRelationshipMethods3(node2, Direction.INCOMING);
			foreach (Relationship rel in node1.getRelationships())
			{
				rel.delete();
			}
			node1.delete();
			node2.delete();
		}

		private void allGetRelationshipMethods(Node node, Direction dir)
		{
			countRelationships(9, node.getRelationships());
			countRelationships(9, node.getRelationships(dir));
			countRelationships(9, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST, MyRelTypes.TEST2, MyRelTypes.TEST_TRAVERSAL }));
			countRelationships(6, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST, MyRelTypes.TEST2 }));
			countRelationships(6, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST, MyRelTypes.TEST_TRAVERSAL }));
			countRelationships(6, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST2, MyRelTypes.TEST_TRAVERSAL }));
			countRelationships(3, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST }));
			countRelationships(3, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST2 }));
			countRelationships(3, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST_TRAVERSAL }));
			countRelationships(3, node.getRelationships(MyRelTypes.TEST, dir));
			countRelationships(3, node.getRelationships(MyRelTypes.TEST2, dir));
			countRelationships(3, node.getRelationships(MyRelTypes.TEST_TRAVERSAL, dir));
		}

		private void allGetRelationshipMethods2(Node node, Direction dir)
		{
			countRelationships(3, node.getRelationships());
			countRelationships(3, node.getRelationships(dir));
			countRelationships(3, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST, MyRelTypes.TEST2, MyRelTypes.TEST_TRAVERSAL }));
			countRelationships(2, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST, MyRelTypes.TEST2 }));
			countRelationships(2, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST, MyRelTypes.TEST_TRAVERSAL }));
			countRelationships(2, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST2, MyRelTypes.TEST_TRAVERSAL }));
			countRelationships(1, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST }));
			countRelationships(1, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST2 }));
			countRelationships(1, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST_TRAVERSAL }));
			countRelationships(1, node.getRelationships(MyRelTypes.TEST, dir));
			countRelationships(1, node.getRelationships(MyRelTypes.TEST2, dir));
			countRelationships(1, node.getRelationships(MyRelTypes.TEST_TRAVERSAL, dir));
		}

		private void allGetRelationshipMethods3(Node node, Direction dir)
		{
			countRelationships(6, node.getRelationships());
			countRelationships(6, node.getRelationships(dir));
			countRelationships(6, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST, MyRelTypes.TEST2, MyRelTypes.TEST_TRAVERSAL }));
			countRelationships(4, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST, MyRelTypes.TEST2 }));
			countRelationships(4, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST, MyRelTypes.TEST_TRAVERSAL }));
			countRelationships(4, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST2, MyRelTypes.TEST_TRAVERSAL }));
			countRelationships(2, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST }));
			countRelationships(2, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST2 }));
			countRelationships(2, node.getRelationships(new RelationshipType[] { MyRelTypes.TEST_TRAVERSAL }));
			countRelationships(2, node.getRelationships(MyRelTypes.TEST, dir));
			countRelationships(2, node.getRelationships(MyRelTypes.TEST2, dir));
			countRelationships(2, node.getRelationships(MyRelTypes.TEST_TRAVERSAL, dir));
		}

		private void countRelationships(int expectedCount, Iterable<Relationship> rels)
		{
			int count = 0;
			foreach (Relationship r in rels)
			{
				count++;
			}
			assertEquals(expectedCount, count);
		}

		public virtual void testRelationshipCreateAndDelete()
		{
			Node node1 = getGraphDb().createNode();
			Node node2 = getGraphDb().createNode();
			Relationship relationship = node1.createRelationshipTo(node2, MyRelTypes.TEST);
			Relationship[] relArray1 = getRelationshipArray(node1.getRelationships());
			Relationship[] relArray2 = getRelationshipArray(node2.getRelationships());
			assertEquals(1, relArray1.Length);
			assertEquals(relationship, relArray1[0]);
			assertEquals(1, relArray2.Length);
			assertEquals(relationship, relArray2[0]);
			relArray1 = getRelationshipArray(node1.getRelationships(MyRelTypes.TEST));
			assertEquals(1, relArray1.Length);
			assertEquals(relationship, relArray1[0]);
			relArray2 = getRelationshipArray(node2.getRelationships(MyRelTypes.TEST));
			assertEquals(1, relArray2.Length);
			assertEquals(relationship, relArray2[0]);
			relArray1 = getRelationshipArray(node1.getRelationships(MyRelTypes.TEST, Direction.OUTGOING));
			assertEquals(1, relArray1.Length);
			relArray2 = getRelationshipArray(node2.getRelationships(MyRelTypes.TEST, Direction.INCOMING));
			assertEquals(1, relArray2.Length);
			relArray1 = getRelationshipArray(node1.getRelationships(MyRelTypes.TEST, Direction.INCOMING));
			assertEquals(0, relArray1.Length);
			relArray2 = getRelationshipArray(node2.getRelationships(MyRelTypes.TEST, Direction.OUTGOING));
			assertEquals(0, relArray2.Length);
			relationship.delete();
			node2.delete();
			node1.delete();
		}

		private Relationship[] getRelationshipArray(Iterable<Relationship> relsIterable)
		{
			List<Relationship> relList = new List<Relationship>();
			foreach (Relationship rel in relsIterable)
			{
				relList.Add(rel);
			}
			return relList.ToArray(new Relationship[relList.Count]);
		}

		public virtual void testDeleteWithRelationship()
		{
		// do some evil stuff
			Node node1 = getGraphDb().createNode();
			Node node2 = getGraphDb().createNode();
			Relationship relationship = node1.createRelationshipTo(node2, MyRelTypes.TEST);
			node1.delete();
			node2.delete();
			Logger log = Logger.getLogger("org.neo4j.kernel.impl.core.NeoConstraintsListener");
			Level level = log.getLevel();
			log.setLevel(Level.OFF);
			try
			{
				getTransaction().success();
				getTransaction().finish();
				fail("deleting node with relaitonship should not commit.");
			}
			catch (Exception e)
			{
			// good
			}
			log.setLevel(level);
			setTransaction(getGraphDb().beginTx());
		}

		public virtual void testDeletedRelationship()
		{
			Node node1 = getGraphDb().createNode();
			Node node2 = getGraphDb().createNode();
			Relationship relationship = node1.createRelationshipTo(node2, MyRelTypes.TEST);
			relationship.delete();
			Logger log = Logger.getLogger("org.neo4j.kernel.impl.core.NeoConstraintsListener");
			Level level = log.getLevel();
			log.setLevel(Level.OFF);
			try
			{
				relationship.setProperty("key1", new int(1));
				fail("Adding property to deleted rel should throw exception.");
			}
			catch (Exception e)
			{ // good
			}
			node1.delete();
			node2.delete();
			log.setLevel(level);
		}

		public virtual void testRelationshipAddProperty()
		{
			Node node1 = getGraphDb().createNode();
			Node node2 = getGraphDb().createNode();
			Relationship rel1 = node1.createRelationshipTo(node2, MyRelTypes.TEST);
			Relationship rel2 = node2.createRelationshipTo(node1, MyRelTypes.TEST);
			try
			{
				rel1.setProperty(null, null);
				fail("Null argument should result in exception.");
			}
			catch (IllegalArgumentException e)
			{
			}
			int int1 = new int(1);
			int int2 = new int(2);
			string string1 = new string("1");
			string string2 = new string("2");

		// add property
			rel1.setProperty(key1, int1);
			rel2.setProperty(key1, string1);
			rel1.setProperty(key2, string2);
			rel2.setProperty(key2, int2);
			assertTrue(rel1.hasProperty(key1));
			assertTrue(rel2.hasProperty(key1));
			assertTrue(rel1.hasProperty(key2));
			assertTrue(rel2.hasProperty(key2));
			assertTrue(!rel1.hasProperty(key3));
			assertTrue(!rel2.hasProperty(key3));
			assertEquals(int1, rel1.getProperty(key1));
			assertEquals(string1, rel2.getProperty(key1));
			assertEquals(string2, rel1.getProperty(key2));
			assertEquals(int2, rel2.getProperty(key2));

			getTransaction().failure();
		}

		public virtual void testRelationshipRemoveProperty()
		{
			int int1 = new int(1);
			int int2 = new int(2);
			string string1 = new string("1");
			string string2 = new string("2");

			Node node1 = getGraphDb().createNode();
			Node node2 = getGraphDb().createNode();
			Relationship rel1 = node1.createRelationshipTo(node2, MyRelTypes.TEST);
			Relationship rel2 = node2.createRelationshipTo(node1, MyRelTypes.TEST);
		// verify that we can rely on PL to reomve non existing properties
			try
			{
				if (rel1.removeProperty(key1) != null)
				{
					fail("Remove of non existing property should return null");
				}
			}
			catch (NotFoundException e)
			{
			}
			try
			{
				rel1.removeProperty(null);
				fail("Remove null property should throw exception.");
			}
			catch (IllegalArgumentException e)
			{
			}

			rel1.setProperty(key1, int1);
			rel2.setProperty(key1, string1);
			rel1.setProperty(key2, string2);
			rel2.setProperty(key2, int2);
			try
			{
				rel1.removeProperty(null);
				fail("Null argument should result in exception.");
			}
			catch (IllegalArgumentException e)
			{
			}

		// test remove property
			assertEquals(int1, rel1.removeProperty(key1));
			assertEquals(string1, rel2.removeProperty(key1));
		// test remove of non exsisting property
			try
			{
				if (rel2.removeProperty(key1) != null)
				{
					fail("Remove of non existing property should return null");
				}
			}
			catch (NotFoundException e)
			{
			// have to set rollback only here
				getTransaction().failure();
			}
			rel1.delete();
			rel2.delete();
			node1.delete();
			node2.delete();
		}

		public virtual void testRelationshipChangeProperty()
		{
			int int1 = new int(1);
			int int2 = new int(2);
			string string1 = new string("1");
			string string2 = new string("2");

			Node node1 = getGraphDb().createNode();
			Node node2 = getGraphDb().createNode();
			Relationship rel1 = node1.createRelationshipTo(node2, MyRelTypes.TEST);
			Relationship rel2 = node2.createRelationshipTo(node1, MyRelTypes.TEST);
			rel1.setProperty(key1, int1);
			rel2.setProperty(key1, string1);
			rel1.setProperty(key2, string2);
			rel2.setProperty(key2, int2);

			try
			{
				rel1.setProperty(null, null);
				fail("Null argument should result in exception.");
			}
			catch (IllegalArgumentException e)
			{
			}
			catch (NotFoundException e)
			{
				fail("wrong exception");
			}

		// test type change of exsisting property
		// cannot test this for now because of exceptions in PL
			rel2.setProperty(key1, int1);

			rel1.delete();
			rel2.delete();
			node2.delete();
			node1.delete();
		}

		public virtual void testRelationshipChangeProperty2()
		{
			int int1 = new int(1);
			int int2 = new int(2);
			string string1 = new string("1");
			string string2 = new string("2");
			bool bool1 = new bool(true);
			bool bool2 = new bool(false);

			Node node1 = getGraphDb().createNode();
			Node node2 = getGraphDb().createNode();
			Relationship rel1 = node1.createRelationshipTo(node2, MyRelTypes.TEST);
			rel1.setProperty(key1, int1);
			rel1.setProperty(key1, int2);
			assertEquals(int2, rel1.getProperty(key1));
			rel1.removeProperty(key1);
			rel1.setProperty(key1, string1);
			rel1.setProperty(key1, string2);
			assertEquals(string2, rel1.getProperty(key1));
			rel1.removeProperty(key1);
			rel1.setProperty(key1, bool1);
			rel1.setProperty(key1, bool2);
			assertEquals(bool2, rel1.getProperty(key1));
			rel1.removeProperty(key1);

			rel1.delete();
			node2.delete();
			node1.delete();
		}

		public virtual void testRelGetProperties()
		{
			int int1 = new int(1);
			int int2 = new int(2);
			string @string = new string("3");

			Node node1 = getGraphDb().createNode();
			Node node2 = getGraphDb().createNode();
			Relationship rel1 = node1.createRelationshipTo(node2, MyRelTypes.TEST);
			try
			{
				rel1.getProperty(key1);
				fail("get non existing property din't throw exception");
			}
			catch (NotFoundException e)
			{
			}
			try
			{
				rel1.getProperty(null);
				fail("get of null key din't throw exception");
			}
			catch (IllegalArgumentException e)
			{
			}
			assertTrue(!rel1.hasProperty(key1));
			assertTrue(!rel1.hasProperty(null));
			rel1.setProperty(key1, int1);
			rel1.setProperty(key2, int2);
			rel1.setProperty(key3, @string);
			assertTrue(rel1.hasProperty(key1));
			assertTrue(rel1.hasProperty(key2));
			assertTrue(rel1.hasProperty(key3));
			try
			{
				rel1.removeProperty(key3);
			}
			catch (NotFoundException e)
			{
				fail("Remove of property failed.");
			}
			assertTrue(!rel1.hasProperty(key3));
			assertTrue(!rel1.hasProperty(null));
			rel1.delete();
			node2.delete();
			node1.delete();
		}

		public virtual void testDirectedRelationship()
		{
			Node node1 = getGraphDb().createNode();
			Node node2 = getGraphDb().createNode();
			Relationship rel2 = node1.createRelationshipTo(node2, MyRelTypes.TEST);
			Relationship rel3 = node2.createRelationshipTo(node1, MyRelTypes.TEST);
			Node[] nodes = rel2.getNodes();
			assertEquals(2, nodes.Length);
			assertTrue(nodes[0].Equals(node1) && nodes[1].Equals(node2));
			nodes = rel3.getNodes();
			assertEquals(2, nodes.Length);
			assertTrue(nodes[0].Equals(node2) && nodes[1].Equals(node1));
			assertEquals(node1, rel2.getStartNode());
			assertEquals(node2, rel2.getEndNode());
			assertEquals(node2, rel3.getStartNode());
			assertEquals(node1, rel3.getEndNode());

			Relationship[] relArray = getRelationshipArray(node1.getRelationships(MyRelTypes.TEST, Direction.OUTGOING));
			assertEquals(1, relArray.Length);
			assertEquals(rel2, relArray[0]);
			relArray = getRelationshipArray(node1.getRelationships(MyRelTypes.TEST, Direction.INCOMING));
			assertEquals(1, relArray.Length);
			assertEquals(rel3, relArray[0]);

			relArray = getRelationshipArray(node2.getRelationships(MyRelTypes.TEST, Direction.OUTGOING));
			assertEquals(1, relArray.Length);
			assertEquals(rel3, relArray[0]);
			relArray = getRelationshipArray(node2.getRelationships(MyRelTypes.TEST, Direction.INCOMING));
			assertEquals(1, relArray.Length);
			assertEquals(rel2, relArray[0]);

			rel2.delete();
			rel3.delete();
			node1.delete();
			node2.delete();
		}

		public virtual void testRollbackDeleteRelationship()
		{
			Node node1 = getGraphDb().createNode();
			Node node2 = getGraphDb().createNode();
			Relationship rel1 = node1.createRelationshipTo(node2, MyRelTypes.TEST);
			newTransaction();
			node1.delete();
			rel1.delete();
			getTransaction().failure();
			getTransaction().finish();
			setTransaction(getGraphDb().beginTx());
			node1.delete();
			node2.delete();
			rel1.delete();
		}

		private void clearCache()
		{
			NeoModule neoModule = ((EmbeddedGraphDatabase) getGraphDb()).getConfig().getNeoModule();
			neoModule.getNodeManager().clearCache();
		}

		public virtual void testCreateRelationshipWithCommitts() // throws NotFoundException
		{
			Node n1 = getGraphDb().createNode();
			newTransaction();
			clearCache();
			n1 = getGraphDb().getNodeById((int) n1.getId());
			Node n2 = getGraphDb().createNode();
			n1.createRelationshipTo(n2, MyRelTypes.TEST);
			newTransaction();
			Relationship[] relArray = getRelationshipArray(n1.getRelationships());
			assertEquals(1, relArray.Length);
			relArray = getRelationshipArray(n1.getRelationships());
			relArray[0].delete();
			n1.delete();
			n2.delete();
		}

		public virtual void testAddPropertyThenDelete()
		{
			Node node1 = getGraphDb().createNode();
			Node node2 = getGraphDb().createNode();
			Relationship rel = node1.createRelationshipTo(node2, MyRelTypes.TEST);
			rel.setProperty("test", "test");
			newTransaction();
			rel.setProperty("test2", "test2");
			rel.delete();
			node1.delete();
			node2.delete();
			newTransaction();
		}

		public virtual void testRelationshipIsType()
		{
			Node node1 = getGraphDb().createNode();
			Node node2 = getGraphDb().createNode();
			Relationship rel = node1.createRelationshipTo(node2, MyRelTypes.TEST);
			assertTrue(rel.isType(MyRelTypes.TEST));
			assertTrue(rel.isType(new RelationshipType() { public string name() { return MyRelTypes.TEST.name(); } }));
			assertFalse(rel.isType(MyRelTypes.TEST_TRAVERSAL));
			rel.delete();
			node1.delete();
			node2.delete();
		}

		public virtual void testChangeProperty()
		{
			Node node1 = getGraphDb().createNode();
			Node node2 = getGraphDb().createNode();
			Relationship rel = node1.createRelationshipTo(node2, MyRelTypes.TEST);
			rel.setProperty("test", "test1");
			newTransaction();
			rel.setProperty("test", "test2");
			rel.removeProperty("test");
			rel.setProperty("test", "test3");
			assertEquals("test3", rel.getProperty("test"));
			rel.removeProperty("test");
			rel.setProperty("test", "test4");
			newTransaction();
			assertEquals("test4", rel.getProperty("test"));
		}

		public virtual void testChangeProperty2()
		{
			Node node1 = getGraphDb().createNode();
			Node node2 = getGraphDb().createNode();
			Relationship rel = node1.createRelationshipTo(node2, MyRelTypes.TEST);
			rel.setProperty("test", "test1");
			newTransaction();
			rel.removeProperty("test");
			rel.setProperty("test", "test3");
			assertEquals("test3", rel.getProperty("test"));
			newTransaction();
			assertEquals("test3", rel.getProperty("test"));
			rel.removeProperty("test");
			rel.setProperty("test", "test4");
			newTransaction();
			assertEquals("test4", rel.getProperty("test"));
		}
	}
}